﻿using CIS.DB;
using CIS.Web.Common;
using CIS.Web.Models;
using CIS.Web.Properties;
using System;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace CIS.Web.Controllers
{
	[RoutePrefix("SysUserGroupMaster")]
	public class SysUserGroupMasterController : BaseDbController
	{
		public ActionResult Index()
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName);

			return View();
		}

		public async Task<JsonCamelCaseResult> GetData(int? page, int? rows, string sort, string order, SysUserGroupMasterModel model)
		{
			int take = rows ?? ConstValues.DefaultGridRows;
			int skip = ((page ?? 1) - 1) * take;

			var sql = DbContext.SysUserGroupMaster.AsNoTracking().Where(x => !string.IsNullOrEmpty(x.Status));

			if (!string.IsNullOrWhiteSpace(model.SelUserGroupName))
			{
				sql = sql.Where(x => x.UserGroupName.Contains(model.SelUserGroupName));
			}

			int total = await sql.CountAsync();

			if (!string.IsNullOrEmpty(sort))
			{
				sql = sql.OrderBy(sort + ConstValues.chrSpace + order).Skip(skip).Take(take);
			}
			else
			{
				sql = sql.OrderBy(x => x.Sort).ThenByDescending(x => x.UpdateDate).ThenBy(x => x.UserGroupName).Skip(skip).Take(take);
			}

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				UserGroupName = x.UserGroupName,
				Status = x.Status,
				Sort = x.Sort,
				Remark = x.Remark,
				Creator = x.Creator,
				CreateIP = x.CreateIP,
				CreateDate = LoginUser.Language == ConstValues.Language.Cn ?
							x.CreateDate.Value.ToString("yyyy-MM-dd") :
							x.CreateDate.Value.ToString("MM/dd/yyyy")
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetEditData(string id)
		{
			var result = await DbContext.SysUserGroupMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ID == id);

			if (result != null)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, result),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<JsonResult> Create(SysUserGroupMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName);

			var result = await DbContext.SysUserGroupMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.UserGroupName == model.UserGroupName);
			if (result != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.UserGroupName)),
						JsonRequestBehavior.AllowGet);
			}

			var sysUserGroupMaster = new SysUserGroupMaster
			{
				ID = Utility.GetTableId(ConstValues.TableName.SysUserGroupMaster),
				UserGroupName = model.UserGroupName?.Trim(),
				Status = model.Status,
				Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort,
				Remark = model.Remark?.Trim(),
				Creator = LoginUser.UserName,
				CreateIP = LoginUser.IP,
				CreateDate = DateTime.Now
			};

			DbContext.SysUserGroupMaster.Add(sysUserGroupMaster);
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<JsonResult> Modify(SysUserGroupMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName);

			var exist = await DbContext.SysUserGroupMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID != model.Id &&
						x.UserGroupName == model.UserGroupName);
			if (exist != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.UserGroupName)),
						JsonRequestBehavior.AllowGet);
			}

			var result = await DbContext.SysUserGroupMaster
					.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				result.UserGroupName = model.UserGroupName?.Trim();
				result.Status = model.Status;
				result.Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort;
				result.Remark = model.Remark?.Trim();
				result.Updater = LoginUser.UserName;
				result.UpdateIP = LoginUser.IP;
				result.UpdateDate = DateTime.Now;

				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<JsonResult> Delete(SysUserGroupMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName);

			var result = await DbContext.SysUserGroupMaster
					.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				using (var transaction = DbContext.Database.BeginTransaction())
				{
					DbContext.SysUserGroupMaster.Remove(result);

					var sysUserAndGroupRelationList = await DbContext.SysUserAndGroupRelation
							.Where(x => x.UserGroupId == model.Id).ToListAsync();
					DbContext.SysUserAndGroupRelation.RemoveRange(sysUserAndGroupRelationList);

					var sysGroupAndRoleRelationList = await DbContext.SysGroupAndRoleRelation
							.Where(x => x.UserGroupId == model.Id).ToListAsync();
					DbContext.SysGroupAndRoleRelation.RemoveRange(sysGroupAndRoleRelationList);

					await DbContext.SaveChangesAsync();
					transaction.Commit();
				}

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		public async Task<JsonCamelCaseResult> GetRoleData(SysUserGroupMasterModel model)
		{
			var sql = DbContext.SysGroupAndRoleRelation.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常 && x.UserGroupId == model.GroupId );
			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				RoleName = DbContext.SysRoleMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.RoleId)?.RoleName,
				GroupName = DbContext.SysUserGroupMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.UserGroupId)?.UserGroupName,
			})
			.OrderBy(x => x.RoleName).ToList();

			return JsonCamelCase(new
			{
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetRole(SysUserGroupMasterModel model)
		{
			var result = await DbContext.SysRoleMaster.AsNoTracking()
				.Where(x => x.Status == ConstValues.Status.正常 )
				.OrderBy(x => x.Sort)
				.ThenBy(x => x.RoleName)
				.Select(x => new
				{
					Id = x.ID,
					ActionName = x.RoleName
				})
				.ToListAsync();

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonResult> CreateRole(SysUserGroupMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName);

			var result = await DbContext.SysGroupAndRoleRelation
				.FirstOrDefaultAsync(x => x.UserGroupId == model.GroupId &&
				    x.RoleId == model.ActionId );
			if (result != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
					string.Format(Resources.MsgRecordExist, Resources.FunctionName)),
					JsonRequestBehavior.AllowGet);
			}

			var SysRoleAndActionRelation = new SysGroupAndRoleRelation
			{
				ID = Utility.GetTableId(ConstValues.TableName.SysGroupAndRoleRelation),
				RoleId = model.ActionId,
				UserGroupId = model.GroupId,
				Status = ConstValues.Status.正常,
				Sort = ConstValues.DefaultSort,
				Remark = string.Empty,
				Creator = LoginUser.UserName,
				CreateIP = LoginUser.IP,
				CreateDate = DateTime.Now
			};

			DbContext.SysGroupAndRoleRelation.Add(SysRoleAndActionRelation);
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
				JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<JsonResult> DeleteRole(SysUserGroupMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName);

			var result = await DbContext.SysGroupAndRoleRelation.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				DbContext.SysGroupAndRoleRelation.Remove(result);
				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
					JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
					JsonRequestBehavior.AllowGet);
			}
		}

		public async Task<JsonCamelCaseResult> GetUserData(SysUserGroupMasterModel model)
		{
			var sql = from relation in DbContext.SysUserAndGroupRelation.AsNoTracking()
					.Where(x => !string.IsNullOrEmpty(x.Status) && x.UserGroupId == model.GroupId)
				join user in DbContext.SysUserMaster.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常)
				on relation.UserId equals user.ID into userinfos
				from userinfo in userinfos.DefaultIfEmpty()
				join usergroup in DbContext.SysUserGroupMaster.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常)
				on relation.UserGroupId equals usergroup.ID into usergroupinfos
				from usergroupinfo in usergroupinfos.DefaultIfEmpty()
				orderby relation.Sort ascending, userinfo.UserName descending
				select new
				{
					Id = relation.ID,
					UserName = userinfo.UserName,
					UserMail = userinfo.Mail,
					Sort = relation.Sort,
					CreateDate = relation.CreateDate
				};

			if (!string.IsNullOrWhiteSpace(model.SelUserNameOrMail))
			{
				sql = sql.Where(x => x.UserName.Contains(model.SelUserNameOrMail) || x.UserMail.Contains(model.SelUserNameOrMail));
			}

			int total = await sql.CountAsync();

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				Id = x.Id,
				UserName = x.UserName,
				Mail = x.UserMail,
				Sort = x.Sort,
				CreateDate = x.CreateDate
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<JsonResult> DeleteUser(SysUserGroupMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName);

			var result = await DbContext.SysUserAndGroupRelation
					.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				DbContext.SysUserAndGroupRelation.Remove(result);
				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
					JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
					JsonRequestBehavior.AllowGet);
			}
		}
	}
}